package zzps.exeed.kernel.convert.impl;

import zzps.exeed.kernel.convert.Converter;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.DoubleAdder;
import java.util.concurrent.atomic.LongAdder;

public class NumberConverter implements Converter<Number> {
    private final Class<? extends Number> targetType;

    public NumberConverter(Class<? extends Number> targetType) {
        this.targetType = targetType;
    }

    @Override
    public Number convert(Object value) {
        if (Byte.class == targetType) {
            if (value instanceof Byte){
                return (Byte)value;
            }else if (value instanceof Number){
                return ((Number) value).byteValue();
            }
            return Byte.valueOf(toStr(value));
        } else if (Short.class == targetType) {
            if (value instanceof Short){
                return (Short)value;
            }else if (value instanceof Number){
                return ((Number) value).shortValue();
            }
            return Short.valueOf(toStr(value));
        } else if (Integer.class == targetType) {
            if (value instanceof Integer){
                return (Integer)value;
            }else if (value instanceof Number){
                return ((Number) value).intValue();
            }
            return Integer.parseInt(toStr(value));
        } else if (Long.class == targetType) {
            if (value instanceof Long){
                return (Long)value;
            }else if (value instanceof Number) {
                return ((Number) value).longValue();
            }
            return Long.parseLong(toStr(value));
        } else if (Float.class == targetType) {
            if(value instanceof Float){
                return (Float)value;
            }else if (value instanceof Number) {
                return ((Number) value).floatValue();
            }
            return Float.parseFloat(toStr(value));
        } else if (Double.class == targetType) {
            if (value instanceof Double){
                return (Double)value;
            }else if (value instanceof Number) {
                return ((Number)value).doubleValue();
            }
            return Double.parseDouble(toStr(value));
        }else if (AtomicInteger.class == targetType) {
            if (value instanceof AtomicInteger){
                return (AtomicInteger)value;
            }else if (value instanceof Number){
                return new AtomicInteger(((Number) value).intValue());
            }
            return new AtomicInteger(Integer.parseInt(toStr(value)));
        } else if (AtomicLong.class == targetType) {
            if (value instanceof AtomicLong){
                return (AtomicLong)value;
            }else if (value instanceof Number){
                return new AtomicLong(((Number) value).intValue());
            }
            return new AtomicLong(Long.parseLong(toStr(value)));
        } else if (LongAdder.class == targetType) {
            if (value instanceof LongAdder){
                return (LongAdder)value;
            }else if (value instanceof Number){
                int intValue = ((Number) value).intValue();
                LongAdder longValue = new LongAdder();
                longValue.add(intValue);
                return longValue;
            }
            LongAdder longValue = new LongAdder();
            int intValue = Integer.parseInt(toStr(value.toString()));
            longValue.add(intValue);
            return longValue;
        }  else if (DoubleAdder.class == targetType) {
            if (value instanceof DoubleAdder){
                return (DoubleAdder)value;
            }else if (value instanceof Number){
                DoubleAdder doubleAdder = new DoubleAdder();
                doubleAdder.add(((Number)value).doubleValue());
                return doubleAdder;
            }
            DoubleAdder doubleAdder = new DoubleAdder();
            doubleAdder.add(Double.parseDouble(toStr(value)));
            return doubleAdder;
        } else if (BigDecimal.class == targetType) {
            if (value instanceof BigDecimal){
                return (BigDecimal)value;
            }else if (value instanceof Number){
                if (value instanceof BigDecimal) {
                    return (BigDecimal) value;
                } else if (value instanceof Long) {
                    return new BigDecimal((Long) value);
                } else if (value instanceof Integer) {
                    return new BigDecimal((Integer) value);
                } else if (value instanceof BigInteger) {
                    return new BigDecimal((BigInteger) value);
                }
            }
            return new BigDecimal(toStr(value));
        } else if (BigInteger.class == targetType) {
            if (value instanceof BigInteger){
                return (BigInteger)value;
            }else if (value instanceof Number){
                return BigInteger.valueOf(((Number) value).longValue());
            }
            return new BigInteger(toStr(value));
        }
        return null;
    }
}
